﻿using System;
using System.Collections.Concurrent;
using System.Net.Sockets;

namespace CS.Beehive
{
    /// <summary>
    /// 可重复使用的SocketAsyncEventArgs对象集合
    /// <remarks>
    /// 核心对象，高效网络通信的核心
    /// http://msdn.microsoft.com/zh-cn/library/vstudio/system.net.sockets.socketasynceventargs(v=vs.100).aspx
    /// </remarks>
    /// </summary>
    public class SocketAsyncEventArgsPool : IDisposable
    {
        protected readonly ConcurrentStack<SocketAsyncEventArgs> Pool;
        private readonly int _maxCapacity;

        /// <summary>
        /// 指定参数specified来初始化池
        /// </summary>
        /// <param name="maxCapacity"></param>
        internal SocketAsyncEventArgsPool(int maxCapacity)
        {
            _maxCapacity = maxCapacity;
            Pool = new ConcurrentStack<SocketAsyncEventArgs>();
            //Pool.Push(new SocketAsyncEventArgs());//至少一个对像存放于池中
        }

        /// <summary>
        /// 数量
        /// </summary>
        public int Count
        {
            get { return Pool.Count; }
        }
        /// <summary>
        /// 最大容量
        /// <remarks>>Todo:超过该容器将阻塞通信</remarks>
        /// </summary>
        public int MaxCapacity
        {
            get { return _maxCapacity; }
        }

        /// <summary>
        /// 压入
        /// <remarks>不能压入空的对象</remarks>
        /// </summary>
        /// <param name="item"></param>
        public void Push(SocketAsyncEventArgs item)
        {
            if (item == null) return;//throw new ArgumentNullException("item", "Items added to a SocketAsyncEventArgsPool cannot be null");
            Pool.Push(item);
        }

        /// <summary>
        /// 弹出
        /// <remarks>必为实例，不为null(池空后创建新的实例)</remarks>
        /// </summary>
        /// <returns></returns>
        public SocketAsyncEventArgs Pop()
        {
            SocketAsyncEventArgs result;
            //return Pool.TryPop(out result) ? result : new SocketAsyncEventArgs();
            Pool.TryPop(out result);
            return result;
        }

        #region IDisposable 成员

        /// <summary>
        /// 释放资源
        /// </summary>
        public void Dispose()
        {
            SocketAsyncEventArgs result;
            while (Pool.TryPop(out result))
            {
                result.Dispose();
            }
            Pool.Clear();
        }

        #endregion

    }
}